package WIAB::Model::Edit;

use strict;
use warnings;
use base 'Catalyst::Model';

use Data::Dumper;

use File::Path;
use Path::Class; # cross platform directory paths
my $base_dir = Path::Class::Dir->new(WIAB->config->{content});
use File::Copy::Recursive qw/dirmove/;
my $txtfixer = Text::FixEOL->new({});

# this fixes cross platform woes during browser-server edit sessions.
use Text::FixEOL;
use File::Slurp;

=head1 move_and_write_content

called if the title of an edit page is changed.  Moves the content
then writes it if legal.  NOT SURE IF THIS IS WORKING.  UNCHECKED!

=cut

sub move_and_write_content {
    my ($self, $page_content, $page_title, $path) = @_;
    my ($error, $dest, $log);
    my $orig_loc = $base_dir->subdir(join '/', @$path);
    if ($page_title eq '') {
        $error = "New page name can not be blank, please go back and try again";
        return $dest, $error
    }
    elsif (! -e "$orig_loc") {
        $error = "The original page " . join '/', @$path . " does not exist.  please contact the site admin " . WIAB->config->{admin_email} . " if the problem persists";
        $log = "original page $orig_loc does not exist";
        return $dest, $error, $log;
    }
    else {
        my $orig_title = pop @$path;
        $page_title =~ s/\s+/_/g;
        push @$path, $page_title;
        my $new_loc = $base_dir->subdir(join '/', @$path);
        if (-e "$new_loc") {
            $error = "The destination page" . join '/', @$path . " already exists.  Please go back and give the page a new title";
            return $dest, $error;
        }
        else {

            eval {
                # TODO - fix for svn
                dirmove ("$orig_loc", "$new_loc");
                my $new_file = $new_loc->file('index.pod');

                # don't change last_modified if minor_edit is
                # checked. here if minor_edit button is checked.
                my $mtime;
                $mtime = (stat "$new_file")[9] if -e "$new_file";
                File::Slurp::write_file("$new_file", "$page_content");
                utime $mtime, $mtime, "$new_file" if $mtime;
            };

            if ($@) {
                $error = "There was a problem writing page " . join ('/', @$path) . ".  Please contact the site administrator " . WIAB->config->{admin_email} ." if the problem persists";
                $log = "problem writing page " . join '/', @$path . " with the error $@";
                return $dest, $error, $log;
            }
            else {
                # successful endpoint
                $dest = $path;
                return $dest, $error, $log;
            }
        }
    }
}

=head1 write_content

Writes the content after an edit.  Called for both newpage and for
edit, if the title is unchanged.

=cut

sub write_content {
    my ($self, $page_content, $page_title, $path) = @_;
    my ($error, $dest, $log);
    my $file_loc = $base_dir->subdir(join '/', @$path)->file('index.pod');
    if (! -e $file_loc) {
        $error = "Can't edit " . join '/', @$path . " as it does not exist." if !-e $file_loc;
        $dest = '/edit/content';
        $dest = $dest . '/' . join '/', @$path if scalar (@$path);
    }
    else {
        # TODO: untaint input here!
        # TODO: add version control here

        # fiddle with mtime and utime if minor edit is checked.
        my $mtime = (stat "$file_loc")[9];
        File::Slurp::write_file("$file_loc", $txtfixer->fix_eol($page_content));
        utime $mtime, $mtime, "$file_loc";

        # set up redirect location after write.
        $dest = '/content';
        $dest = $dest . '/' . join '/', @$path if scalar(@$path);
    }
    return $dest, $error, $log;
}



=head1 addpage

writes the new page.  Controller takes care of everything about the
location of the page before it gets here, so this sub is basically
just a worker.

=cut

sub addpage {
    my ($self, $title, $content, $path) = @_;
    my ($dest, $error);
    push @$path, $title;
    my $dest_dir = $base_dir->subdir(join '/', @$path );
    eval {
        mkdir "$dest_dir";
    };
    if ($@ or $@ ne '') {
        $error = $@;
        pop @$path;
        $dest = $path;
    }
    else {
        my $dest_file = $dest_dir->file('index.pod');
        eval {
            # fiddle with mtime and utime if minor edit is checked
            my $mtime;
            $mtime = (stat "$dest_file")[9] if -e "$dest_file";
            # warning below
                File::Slurp::write_file("$dest_file", $txtfixer->fix_eol($content));
            if ($mtime) {
                utime $mtime, $mtime, "$dest_file";
            }
        };
        if ($@) {
            $error = $@;
            $dest = '/edit/content/newpage';
            $dest = $dest . '/' . join '/', @$path if scalar(@$path);
        }
        else {
            $dest = '/content';
            $dest = $dest . '/' . join '/', @$path if scalar(@$path);
        }
        return $dest, $error;
    }
}

=head1 are_children

utility function to determine if we're at a terminal node or not.
Needs to be refactored into utility class.  see
L<WIAB::Model::Content#is_terminal> for example.

=cut

sub are_children {
    my ($self, $path) = @_;
    my $DH;
    opendir $DH, $path;
    my @subdirs = grep { -d $path->subdir($_) && !/^\./ && !/^\.svn$/} readdir $DH;
    return scalar(@subdirs);
}


=head1 NAME

WIAB::Model::Edit - Catalyst Model

=head1 SYNOPSIS

See L<WIAB>

=head1 DESCRIPTION

Catalyst Model.

=head1 AUTHOR

Kieren Diment

=head1 LICENSE

This library is free software, you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut

1;
